import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;

class IntelligentChatService {
  static const String _baseApiUrl =
      'https://open.bigmodel.cn/api/paas/v4/chat/completions';
  static const String _authToken =
      '5beaeb9f4fba45868ac1897befd13bd8.diwxCpLrwzIpqefE';
  static const String _modelVersion = 'glm-4v-plus-0111';

  final Random _randomGenerator = Random();
  late final HttpClient _httpClient;

  IntelligentChatService() {
    _initializeHttpClient();
  }

  void _initializeHttpClient() {
    _httpClient = HttpClient();
    _httpClient.connectionTimeout = const Duration(seconds: 30);
    _httpClient.idleTimeout = const Duration(seconds: 30);
  }

  String _generateUniqueId() {
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final randomValue = _randomGenerator.nextInt(999999);
    return '${timestamp}_$randomValue';
  }

  Future<Map<String, dynamic>> _sendHttpRequest(
    Map<String, dynamic> payload,
  ) async {
    try {
      final uri = Uri.parse(_baseApiUrl);
      final request = await _httpClient.postUrl(uri);

      request.headers.set('Content-Type', 'application/json');
      request.headers.set('Authorization', 'Bearer $_authToken');

      final jsonPayload = jsonEncode(payload);
      request.write(jsonPayload);

      final response = await request.close();
      final responseBody = await response.transform(utf8.decoder).join();

      if (response.statusCode == 200) {
        final responseData = jsonDecode(responseBody);
        return {'success': true, 'data': responseData};
      } else {
        return {
          'success': false,
          'error': 'API request failed with status: ${response.statusCode}',
          'details': responseBody,
        };
      }
    } catch (error) {
      return {
        'success': false,
        'error': 'Network request failed',
        'details': error.toString(),
      };
    }
  }

  Future<String> storeImageFileLocally(File imageFile) async {
    try {
      final appDocumentDirectory = await getApplicationDocumentsDirectory();
      final chatImagesDirectory = Directory(
        '${appDocumentDirectory.path}/chat_images',
      );

      if (!await chatImagesDirectory.exists()) {
        await chatImagesDirectory.create(recursive: true);
      }

      final uniqueFileName =
          '${_generateUniqueId()}${path.extension(imageFile.path)}';
      final savedImageFile = await imageFile.copy(
        '${chatImagesDirectory.path}/$uniqueFileName',
      );
      return savedImageFile.path;
    } catch (error) {
      return imageFile.path;
    }
  }

  Future<String> convertImageToBase64(File imageFile) async {
    try {
      final imageBytes = await imageFile.readAsBytes();
      return base64Encode(imageBytes);
    } catch (error) {
      throw Exception('Failed to convert image to base64: $error');
    }
  }

  Future<Map<String, dynamic>> sendImageWithTextMessage({
    required String userIdentifier,
    required File imageFile,
    required String textMessage,
  }) async {
    try {
      final localImagePath = await storeImageFileLocally(imageFile);

      final base64ImageData = await convertImageToBase64(imageFile);

      final apiRequestPayload = {
        'model': _modelVersion,
        'messages': [
          {
            'role': 'user',
            'content': [
              {
                'type': 'image_url',
                'image_url': {'url': 'data:image/jpeg;base64,$base64ImageData'},
              },
              {
                'type': 'text',
                'text': '$textMessage\n\nPlease respond in English.',
              },
            ],
          },
        ],
        'temperature': 0.7,
        'max_tokens': 2000,
      };

      final response = await _sendHttpRequest(apiRequestPayload);

      if (response['success']) {
        final responseData = response['data'];
        final aiResponseContent =
            responseData['choices'][0]['message']['content'];

        return {
          'success': true,
          'response': aiResponseContent,
          'localImagePath': localImagePath,
          'timestamp': DateTime.now().millisecondsSinceEpoch,
        };
      } else {
        return response;
      }
    } catch (generalError) {
      return {
        'success': false,
        'error': 'Request processing failed',
        'details': generalError.toString(),
      };
    }
  }

  Future<Map<String, dynamic>> continueTextConversation({
    required String textMessage,
    required List<Map<String, String>> conversationHistory,
  }) async {
    try {
      final messageHistory =
          conversationHistory
              .map(
                (historyItem) => {
                  'role': historyItem['role'],
                  'content': historyItem['content'],
                },
              )
              .toList();

      messageHistory.insert(0, {
        'role': 'system',
        'content':
            'You are a helpful AI assistant. Please always respond in English, regardless of the language used in the user\'s message.',
      });

      // messageHistory.add({'role': 'user', 'content': textMessage});
      messageHistory.add({
        'role': 'user',
        'content': '$textMessage\n\nPlease respond in English.',
      });

      final apiRequestPayload = {
        'model': _modelVersion,
        'messages': messageHistory,
        'temperature': 0.7,
        'max_tokens': 2000,
      };

      final response = await _sendHttpRequest(apiRequestPayload);

      if (response['success']) {
        final responseData = response['data'];
        final aiResponseContent =
            responseData['choices'][0]['message']['content'];

        return {
          'success': true,
          'response': aiResponseContent,
          'timestamp': DateTime.now().millisecondsSinceEpoch,
        };
      } else {
        return response;
      }
    } catch (generalError) {
      return {
        'success': false,
        'error': 'Request processing failed',
        'details': generalError.toString(),
      };
    }
  }

  void dispose() {
    _httpClient.close();
  }
}

class ChatMessageModel {
  final String messageId;
  final String content;
  final bool isFromUser;
  final DateTime timestamp;
  final String? imagePath;

  ChatMessageModel({
    required this.messageId,
    required this.content,
    required this.isFromUser,
    required this.timestamp,
    this.imagePath,
  });

  factory ChatMessageModel.fromJson(Map<String, dynamic> json) {
    return ChatMessageModel(
      messageId: json['messageId'],
      content: json['content'],
      isFromUser: json['isFromUser'],
      timestamp: DateTime.fromMillisecondsSinceEpoch(json['timestamp']),
      imagePath: json['imagePath'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'messageId': messageId,
      'content': content,
      'isFromUser': isFromUser,
      'timestamp': timestamp.millisecondsSinceEpoch,
      'imagePath': imagePath,
    };
  }
}
